home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / dev / ds5000.md / devGraphics.c < prev    next >
C/C++ Source or Header  |  1991-05-08  |  43KB  |  1,868 lines

  1. /* 
  2.  *  devGraphics.c --
  3.  *
  4.  *         This file contains machine-dependent routines for the graphics device.
  5.  *
  6.  *    Most of this assumes that you have a standard color frame buffer.
  7.  *    Support for the fancier graphics displays does not exist yet.
  8.  *
  9.  *    Copyright (C) 1989 Digital Equipment Corporation.
  10.  *    Permission to use, copy, modify, and distribute this software and
  11.  *    its documentation for any purpose and without fee is hereby granted,
  12.  *    provided that the above copyright notice appears in all copies.  
  13.  *    Digital Equipment Corporation makes no representations about the
  14.  *    suitability of this software for any purpose.  It is provided "as is"
  15.  *    without express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /sprite/src/kernel/dev/ds5000.md/RCS/devGraphics.c,v 1.5 91/05/08 16:29:24 jhh Exp $ SPRITE (DECWRL)";
  20. #endif not lint
  21.  
  22. #include <sprite.h>
  23. #include <machMon.h>
  24. #include <mach.h>
  25. #include <dev.h>
  26. #include <fs.h>
  27. #include <fsio.h>
  28. #include <sys.h>
  29. #include <sync.h>
  30. #include <timer.h>
  31. #include <dbg.h>
  32. #include <machAddrs.h>
  33. #include <console.h>
  34. #include <dc7085.h>
  35. #include <graphics.h>
  36. #include <vm.h>
  37. #include <vmMach.h>
  38. #include <dev/graphics.h>
  39. #include <devGraphicsInt.h>
  40.  
  41. /*
  42.  * Macro to translate from a time struct to milliseconds.
  43.  */
  44. #define TO_MS(time) ((time.seconds * 1000) + (time.microseconds / 1000))
  45.  
  46.  
  47. Boolean    devGraphicsOpen = FALSE;        /* TRUE => the mouse is open.*/
  48.                     /* Process waiting for select.*/
  49.  
  50. typedef struct {
  51.     char    *vendor;
  52.     char    *module;
  53.     int        romOffset;
  54.     int        type;
  55. } DisplayInfo;
  56.  
  57. DisplayInfo    configDisplays[] = {
  58.     {"DEC", "PMAG-BA", PMAGBA_ROM_OFFSET, PMAGBA},
  59.     {"DEC", "PMAG-DA", 0, PMAGBA},
  60. };
  61. int numConfigDisplays = sizeof(configDisplays) / sizeof(DisplayInfo);
  62.  
  63. /*
  64.  * Redefine MASTER_LOCK to be DISABLE_INTR for two reasons.  First, it
  65.  * is more efficient and sufficient on a uni-processor.  Second, MASTER_LOCK
  66.  * can cause deadlock because this file contains the routine which blits
  67.  * a character to the screen.  As a result no routine in here can do a printf
  68.  * underneath the MASTER_LOCK because the Blitc routine grabs the master lock.
  69.  * Once things are debugged and the printfs are removed it should be OK to use
  70.  * a TRUE master lock.
  71.  */
  72. #ifdef MASTER_LOCK
  73. #undef MASTER_LOCK
  74. #undef MASTER_UNLOCK
  75. #endif
  76. #define MASTER_LOCK(mutexPtr)    DISABLE_INTR()
  77. #define MASTER_UNLOCK(mutexPtr)    ENABLE_INTR()
  78.  
  79. /*
  80.  * These need to mapped into user space.
  81.  */
  82. static DevScreenInfo    scrInfoCached;
  83. static DevEvent        eventsCached[DEV_MAXEVQ] = {0};    
  84. static DevTimeCoord    tcsCached[MOTION_BUFFER_SIZE] = {0};
  85. static char        *frameBuffer = (char *) NIL;
  86.  
  87. static DevScreenInfo    *scrInfoPtr;
  88. static DevEvent        *events;
  89. static DevTimeCoord    *tcs;
  90.  
  91. static unsigned short    cursorBits [32];
  92.  
  93. Boolean            inKBDReset = FALSE;
  94.  
  95. Address            mappedAddrs[5];
  96.  
  97. /*
  98.  * DEBUGGING STUFF.
  99.  */
  100.  
  101. #define DEBUG_SIZE    256
  102. #define DEBUG_ADD    1
  103. #define DEBUG_UPDATE    2
  104. #define DEBUG_PTR(ptr) {             \
  105.     if (debugPtr == &debugArray[DEBUG_SIZE]) {    \
  106.     debugPtr = debugArray;            \
  107.     }                        \
  108.     ptr = debugPtr++;                \
  109. }
  110.  
  111. Boolean            devGraphicsDebug = TRUE;
  112. typedef struct {
  113.     int        type;
  114.     int        x;
  115.     int        y;
  116. } DebugInfo;
  117.  
  118. DebugInfo        debugArray[DEBUG_SIZE];
  119. DebugInfo        *debugPtr = debugArray;
  120.  
  121. int foo;
  122. int bar;
  123. /*
  124.  * END OF DEBUGGING STUFF.
  125.  */
  126.  
  127. MouseReport        lastRep;
  128. MouseReport        currentRep;
  129.  
  130. static unsigned char bgRgb[3];    /* background and foreground colors     */
  131. static unsigned char fgRgb[3];  /*     for the cursor. */
  132.  
  133. /*
  134.  * Keyboard defaults.
  135.  */
  136. static short divDefaults[15] = { 
  137.     LK_DOWN,    /* 0 doesn't exist */
  138.     LK_AUTODOWN, 
  139.     LK_AUTODOWN, 
  140.     LK_AUTODOWN, 
  141.     LK_DOWN,
  142.     LK_UPDOWN,   
  143.     LK_UPDOWN,   
  144.     LK_AUTODOWN, 
  145.     LK_AUTODOWN, 
  146.     LK_AUTODOWN, 
  147.     LK_AUTODOWN, 
  148.     LK_AUTODOWN, 
  149.     LK_AUTODOWN, 
  150.     LK_DOWN, 
  151.     LK_AUTODOWN 
  152. };
  153.  
  154. /* 
  155.  * Keyboard initialization string.
  156.  */
  157. short kbdInitString[] = {        /* reset any random keyboard stuff */
  158.     LK_AR_ENABLE,            /* we want autorepeat by default */
  159.     LK_CL_ENABLE,            /* keyclick */
  160.     0x84,                /* keyclick volume */
  161.     LK_KBD_ENABLE,            /* the keyboard itself */
  162.     LK_BELL_ENABLE,            /* keyboard bell */
  163.     0x84,                /* bell volume */
  164.     LK_LED_DISABLE,            /* keyboard leds */
  165.     LED_ALL
  166. };
  167.  
  168. #define KBD_INIT_LENGTH    sizeof(kbdInitString) / sizeof(short)
  169.  
  170.  
  171. /*
  172.  * The default cursor.  The X server does things in terms of the ds3100,
  173.  * which had the notion of A and B planes.  The LoadCursor routine
  174.  * converts this into the correct format.
  175.  */
  176.  
  177. unsigned short defCursor[32] = { 
  178. /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
  179.           0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
  180. /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
  181.               0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
  182.  
  183. };
  184. /*
  185.  * Font mask bits used by Blitc().
  186.  */
  187. static unsigned int fontmaskBits[16] = {
  188.     0x00000000,
  189.     0x00000001,
  190.     0x00000100,
  191.     0x00000101,
  192.     0x00010000,
  193.     0x00010001,
  194.     0x00010100,
  195.     0x00010101,
  196.     0x01000000,
  197.     0x01000001,
  198.     0x01000100,
  199.     0x01000101,
  200.     0x01010000,
  201.     0x01010001,
  202.     0x01010100,
  203.     0x01010101
  204. };
  205.  
  206. static Boolean initialized = FALSE;
  207.  
  208. /*
  209.  * Mutex to synchronize access.
  210.  */
  211. Sync_Semaphore graphicsMutex;
  212.  
  213. /*
  214.  * Token used to notify process that has graphics device open that events
  215.  * are available.
  216.  */
  217. ClientData    notifyToken;
  218.  
  219. /*
  220.  * Forward references.
  221.  */
  222. static void        InitScreenDefaults();
  223. static void        ScreenInit();
  224. static void        LoadCursor();
  225. static void        RestoreCursorColor();
  226. static void        CursorColor();
  227. static void        MouseInit();
  228. static void        KBDReset();
  229. static void        InitColorMap();
  230. static void        RAMDACInit();
  231. static void        LoadColorMap();
  232. static void         RecvIntr();
  233. static void        MouseEvent();
  234. static void        MouseButtons();
  235. static void        PosCursor();
  236. static void        XmitIntr();
  237. static void        Scroll();
  238. static void        Blitc();
  239.  
  240.  
  241. typedef struct ramdac {
  242.     unsigned char        *addrLowPtr;
  243.     unsigned char        *addrHighPtr;
  244.     volatile unsigned char    *regPtr;
  245.     volatile unsigned char    *colorMap;
  246. } Ramdac;
  247.  
  248. static Ramdac     ramdac;
  249. static int     planeMask;
  250. static int    displayType = UNKNOWN;
  251.  
  252.  
  253. /*
  254.  * ----------------------------------------------------------------------------
  255.  *
  256.  * DevGraphicsInit --
  257.  *
  258.  *    Initialize the mouse and the screen.
  259.  *
  260.  * Results:
  261.  *    None.
  262.  *
  263.  * Side effects:
  264.  *    The world is initialized.
  265.  *
  266.  * ----------------------------------------------------------------------------
  267.  */
  268. void
  269. DevGraphicsInit()
  270. {
  271.     Time        time;
  272.     int            i;
  273.     int            slot;
  274.     Mach_SlotInfo    slotInfo;
  275.     ReturnStatus    status;
  276.     char        *slotAddr;
  277.     DisplayInfo        *displayInfoPtr = (DisplayInfo *) NIL;
  278.  
  279.     Sync_SemInitDynamic(&graphicsMutex, "graphicsMutex");
  280.     for (i = 0; i < numConfigDisplays; i++) {
  281.     displayInfoPtr = &configDisplays[i];
  282.     for (slot = 0; slot < 3; slot++) {
  283.         slotAddr = (char *) MACH_IO_SLOT_ADDR(slot);
  284.         status = Mach_GetSlotInfo(slotAddr + displayInfoPtr->romOffset, 
  285.             &slotInfo);
  286.         if (status == SUCCESS) {
  287.         if ((!strcmp(slotInfo.vendor, displayInfoPtr->vendor)) && 
  288.             (!strcmp(slotInfo.module, displayInfoPtr->module))) {
  289.             displayType = displayInfoPtr->type;
  290.             break;
  291.         }
  292.         }
  293.     }
  294.     if (displayType != UNKNOWN) {
  295.         break;
  296.     }
  297.     }
  298.     switch (displayType) {
  299.     case UNKNOWN :
  300.         Mach_MonPrintf(
  301.         "Assuming you have one of those fancy graphics displays.\n");
  302.         displayType = PMAGDA;
  303.         break;
  304.     case PMAGBA:
  305.         Mach_MonPrintf("Color frame buffer in slot %d, (%s %s %s %s)\n",
  306.             slot, slotInfo.module, slotInfo.vendor,
  307.             slotInfo.revision, slotInfo.type);
  308.         break;
  309.     }
  310.     if (displayType == PMAGBA) {
  311.     ramdac.addrLowPtr = (unsigned char *) (slotAddr + PMAGBA_RAMDAC_OFFSET);
  312.     ramdac.addrHighPtr = (unsigned char *) 
  313.                 (slotAddr + PMAGBA_RAMDAC_OFFSET + 0x4);
  314.     ramdac.regPtr = (unsigned char *) 
  315.                 (slotAddr + PMAGBA_RAMDAC_OFFSET + 0x8);
  316.     ramdac.colorMap = (unsigned char *) 
  317.                 (slotAddr + PMAGBA_RAMDAC_OFFSET + 0xc);
  318.  
  319.     /*
  320.      * Initialize screen info.
  321.      */
  322.     scrInfoPtr = (DevScreenInfo *) MACH_UNCACHED_ADDR(&scrInfoCached);
  323.     events = (DevEvent *) MACH_UNCACHED_ADDR(eventsCached);
  324.     tcs = (DevTimeCoord *)  MACH_UNCACHED_ADDR(tcsCached);
  325.  
  326.     InitScreenDefaults(scrInfoPtr);
  327.     scrInfoPtr->eventQueue.events = events;
  328.     scrInfoPtr->eventQueue.tcs = tcs;
  329.     frameBuffer = (char *) (slotAddr + PMAGBA_BUFFER_OFFSET);
  330.     scrInfoPtr->bitmap = (char *) frameBuffer;
  331.     scrInfoPtr->cursorBits = (short *)(cursorBits);
  332.     Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  333.     scrInfoPtr->eventQueue.timestampMS = TO_MS(time);
  334.     scrInfoPtr->eventQueue.eSize = DEV_MAXEVQ;
  335.     scrInfoPtr->eventQueue.eHead = scrInfoPtr->eventQueue.eTail = 0;
  336.     scrInfoPtr->eventQueue.tcSize = MOTION_BUFFER_SIZE;
  337.     scrInfoPtr->eventQueue.tcNext = 0;
  338.  
  339.     /*
  340.      * Initialize the color map, and the screen, and the mouse.
  341.      */
  342.     InitColorMap();
  343.     ScreenInit();
  344.     }
  345.     MouseInit();
  346.     Scroll();
  347.  
  348.     /*
  349.      * Init the "latest mouse report" structure
  350.      */
  351.     lastRep.state = 0;
  352.     lastRep.dx = 0;
  353.     lastRep.dy = 0;
  354.     lastRep.byteCount = 0;
  355.  
  356.  
  357.     /*
  358.      * Reset the keyboard.
  359.      */
  360.     if(!inKBDReset) {
  361.     KBDReset();
  362.     }
  363.  
  364.     if (displayType == PMAGBA) {
  365.     /*
  366.      * Clear any pending video interrupts.
  367.      */
  368.  
  369.     * ((int *) (slotAddr + PMAGBA_IREQ_OFFSET)) = 1;
  370.     }
  371.  
  372.     initialized = TRUE;
  373.  
  374.     bzero((char *) debugArray, sizeof(debugArray));
  375. }    
  376.  
  377.  
  378. /*
  379.  * ----------------------------------------------------------------------------
  380.  *
  381.  * InitScreenDefaults --
  382.  *
  383.  *    Set up default screen parameters.
  384.  *
  385.  * Results:
  386.  *    None.
  387.  *
  388.  * Side effects:
  389.  *    *scrInfoPtr is filled in with default screen parameters.
  390.  *
  391.  * ----------------------------------------------------------------------------
  392.  */
  393. static void
  394. InitScreenDefaults(scrInfoPtr)
  395.     DevScreenInfo    *scrInfoPtr;
  396. {
  397.     bzero((char *)scrInfoPtr, sizeof(DevScreenInfo));
  398.     scrInfoPtr->maxRow = 56;
  399.     scrInfoPtr->maxCol = 80;
  400.     scrInfoPtr->maxX = 1024;
  401.     scrInfoPtr->maxY = 864;
  402.     scrInfoPtr->maxCurX = 1023;
  403.     scrInfoPtr->maxCurY = 863;
  404.     scrInfoPtr->version = 11;
  405.     scrInfoPtr->mthreshold = 4;    
  406.     scrInfoPtr->mscale = 2;
  407.     scrInfoPtr->minCurX = -15;
  408.     scrInfoPtr->minCurY = -15;
  409. }
  410.  
  411.  
  412. /*
  413.  * ----------------------------------------------------------------------------
  414.  *
  415.  * ScreenInit --
  416.  *
  417.  *    Initialize the screen.
  418.  *
  419.  * Results:
  420.  *    None.
  421.  *
  422.  * Side effects:
  423.  *    The screen is initialized.
  424.  *
  425.  * ----------------------------------------------------------------------------
  426.  */
  427. static void
  428. ScreenInit()
  429. {
  430.     int    i;
  431.     int addr;
  432.     /*
  433.      * Home the cursor.
  434.      * We want an LSI terminal emulation.  We want the graphics
  435.      * terminal to scroll from the bottom. So start at the bottom.
  436.      */
  437.     scrInfoPtr->row = 55;
  438.     scrInfoPtr->col = 0;
  439.  
  440.     /*
  441.      * Load the cursor with the default values
  442.      *
  443.      */
  444.     LoadCursor(defCursor);
  445.  
  446.     /*
  447.      * Reset keyboard to default state.
  448.      */
  449.      if(!inKBDReset) {
  450.      KBDReset();
  451.      }
  452. }
  453.  
  454.  
  455. /*
  456.  * ----------------------------------------------------------------------------
  457.  *
  458.  * LoadCursor --
  459.  *
  460.  *    Routine to load the cursor Sprite pattern.  The hardware cursor is
  461.  *    64x64x2.  Each byte loaded into the bt459 is 4 pixels (2 bits each),
  462.  *    and the most-significant bit is the leftmost on the screen.
  463.  *    The parameter to this routine is an array of bytes, in the format
  464.  *    used by the ds3100.  The array can be thought of as two arrays
  465.  *    of 16-bit words each with 16 words.  The first array is one bit
  466.  *     for each pixel, and the second array is the other bit.  Also, the
  467.  *    least-significant bit of the byte is the leftmost on the screen, and
  468.  *    the cursor is 16x16.  This routine has to convert between the
  469.  *    two formats, hence the mess.  Any unused bits in the hardware
  470.  *    cursor are set to 0.
  471.  *
  472.  * Results:
  473.  *    None.
  474.  *
  475.  * Side effects:
  476.  *    The cursor is loaded into the hardware cursor.
  477.  *
  478.  * ----------------------------------------------------------------------------
  479.  */
  480. static void
  481. LoadCursor(curPtr)
  482.     unsigned char *curPtr;
  483. {
  484.     register int i, j;
  485.     int addr;
  486.     unsigned char value, a, b;
  487.     unsigned char *aPtr, *bPtr;
  488.  
  489.     aPtr = curPtr;
  490.     bPtr = curPtr + 32;
  491.     addr = 0x400;
  492.     *ramdac.addrHighPtr = (addr >> 8);
  493.     *ramdac.addrLowPtr = (addr & 0xff);
  494.     Mach_EmptyWriteBuffer();
  495.     for (i = 0; i < 16; i++) {
  496.     for (j = 0; j < 4; j += 2) {
  497.         a = *aPtr;
  498.         b = *bPtr;
  499.         value = ((a << 7) & 0x80) |
  500.             ((b << 6) & 0x40) |
  501.             ((a << 4) & 0x20) |
  502.             ((b << 3) & 0x10) |
  503.             ((a << 1) & 0x08) |
  504.             ((b << 0) & 0x04) |
  505.             ((a >> 2) & 0x02) |
  506.             ((b >> 3) & 0x01);
  507.         *ramdac.regPtr = value;
  508.         Mach_EmptyWriteBuffer();
  509.         value = ((a << 3) & 0x80) |
  510.             ((b << 2) & 0x40) |
  511.             ((a << 0) & 0x20) |
  512.             ((b >> 1) & 0x10) |
  513.             ((a >> 3) & 0x08) |
  514.             ((b >> 4) & 0x04) |
  515.             ((a >> 6) & 0x02) |
  516.             ((b >> 7) & 0x01);
  517.         *ramdac.regPtr = value;
  518.         Mach_EmptyWriteBuffer();
  519.         aPtr++;
  520.         bPtr++;
  521.     }
  522.     for(; j < 16; j++) {
  523.         *ramdac.regPtr = 0;
  524.         Mach_EmptyWriteBuffer();
  525.     }
  526.     }
  527.     for (; i < 64; i++) {
  528.     for (j = 0; j < 16; j++) {
  529.         *ramdac.regPtr = 0;
  530.         Mach_EmptyWriteBuffer();
  531.     }
  532.     }
  533. }
  534.  
  535.  
  536. /*
  537.  * ----------------------------------------------------------------------------
  538.  *
  539.  * RestoreCursorColor --
  540.  *
  541.  *    Routine to restore the color of the cursor.
  542.  *
  543.  * Results:
  544.  *    None.
  545.  *
  546.  * Side effects:
  547.  *    None.
  548.  *
  549.  * ----------------------------------------------------------------------------
  550.  */
  551. static void
  552. RestoreCursorColor()
  553. {
  554.     register int i;
  555.  
  556.  
  557.     *ramdac.addrHighPtr = 0x1;
  558.     *ramdac.addrLowPtr = 0x81;
  559.     Mach_EmptyWriteBuffer();
  560.     for (i=0; i < 3; i++) {  
  561.     *ramdac.regPtr = bgRgb[i];
  562.     Mach_EmptyWriteBuffer();
  563.     }
  564.  
  565.     *ramdac.addrHighPtr = 0x1;
  566.     *ramdac.addrLowPtr = 0x82;
  567.     Mach_EmptyWriteBuffer();
  568.     for (i=0; i < 3; i++) {  
  569.     *ramdac.regPtr = fgRgb[i];
  570.     Mach_EmptyWriteBuffer();
  571.     }
  572. }
  573.  
  574.  
  575. /*
  576.  * ----------------------------------------------------------------------------
  577.  *
  578.  * CursorColor --
  579.  *
  580.  *    Set the color of the cursor.
  581.  *
  582.  * Results:
  583.  *    None.
  584.  *
  585.  * Side effects:
  586.  *    None.
  587.  *
  588.  * ----------------------------------------------------------------------------
  589.  */
  590. static void
  591. CursorColor(color)
  592.     unsigned int color[];
  593. {
  594.     register int i, j;
  595.     for (i = 0; i < 3; i++) {
  596.     bgRgb[i] = (unsigned char )(color[i] >> 8);
  597.     }
  598.     for (j = 0; j < 3; j++) {
  599.     fgRgb[i] = (unsigned char )(color[j] >> 8);
  600.     }
  601.     RestoreCursorColor();
  602. }
  603.  
  604.  
  605. /*
  606.  * ----------------------------------------------------------------------------
  607.  *
  608.  * MouseInit --
  609.  *
  610.  *    Initialize the mouse.
  611.  *
  612.  * Results:
  613.  *    None.
  614.  *
  615.  * Side effects:
  616.  *    None.
  617.  *
  618.  * ----------------------------------------------------------------------------
  619.  */
  620. static void
  621. MouseInit()
  622. {
  623.     int    id_byte1, id_byte2, id_byte3, id_byte4;
  624.  
  625.     /*
  626.      * Initialize the mouse.
  627.      */
  628.     DevDC7085MouseInit();
  629.     DevDC7085MousePutCh(MOUSE_SELF_TEST);
  630.     id_byte1 = DevDC7085MouseGetCh();
  631.     if (id_byte1 < 0) {
  632.     printf("MouseInit: Timeout on 1st byte of self-test report\n");
  633.     return;
  634.     }
  635.     id_byte2 = DevDC7085MouseGetCh();
  636.     if (id_byte2 < 0) {
  637.     printf("MouseInit: Timeout on 2nd byte of self-test report\n");
  638.     return;
  639.     }
  640.     id_byte3 = DevDC7085MouseGetCh();
  641.     if (id_byte3 < 0) {
  642.     printf("MouseInit: Timeout on 3rd byte of self-test report\n");
  643.     return;
  644.     }
  645.     id_byte4 = DevDC7085MouseGetCh();
  646.     if (id_byte4 < 0) {
  647.     printf("MouseInit: Timeout on 4th byte of self-test report\n");
  648.     return;
  649.     }
  650.     if ((id_byte2 & 0x0f) != 0x2) {
  651.     printf("MouseInit: We don't have a mouse!!!\n");
  652.     }
  653.     DevDC7085MousePutCh(MOUSE_INCREMENTAL);
  654. }
  655.  
  656.  
  657. /*
  658.  * ----------------------------------------------------------------------------
  659.  *
  660.  * KBDReset --
  661.  *
  662.  *    Reset the keyboard to default characteristics.
  663.  *
  664.  * Results:
  665.  *    None.
  666.  *
  667.  * Side effects:
  668.  *    None.
  669.  *
  670.  * ----------------------------------------------------------------------------
  671.  */
  672. static void
  673. KBDReset()
  674. {
  675.     register int i;
  676.  
  677.     inKBDReset = TRUE;
  678.     DevDC7085KBDPutc(LK_DEFAULTS);
  679.     for (i=1; i < 15; i++) {
  680.     DevDC7085KBDPutc(divDefaults[i] | (i << 3));
  681.     }
  682.     for (i = 0; i < KBD_INIT_LENGTH; i++) {
  683.     DevDC7085KBDPutc ((int)kbdInitString[i]);
  684.     }
  685.     inKBDReset = FALSE;
  686. }
  687.  
  688.  
  689. /*
  690.  * ----------------------------------------------------------------------------
  691.  *
  692.  * InitColorMap --
  693.  *
  694.  *    Initialize the color map.
  695.  *
  696.  * Results:
  697.  *    None.
  698.  *
  699.  * Side effects:
  700.  *    The colormap is initialized appropriately whether it is color or 
  701.  *    monochrome.
  702.  *
  703.  * ----------------------------------------------------------------------------
  704.  */
  705. static void
  706. InitColorMap()
  707. {
  708.     register int i;
  709.  
  710.     RAMDACInit();
  711.  
  712.     *ramdac.addrHighPtr = 0;
  713.     *ramdac.addrLowPtr = 0;
  714.     Mach_EmptyWriteBuffer();
  715.     *ramdac.colorMap = 0;
  716.     Mach_EmptyWriteBuffer();
  717.     *ramdac.colorMap = 0;
  718.     Mach_EmptyWriteBuffer();
  719.     *ramdac.colorMap = 0;
  720.     Mach_EmptyWriteBuffer();
  721.     for(i = 1; i < 256; i++) {
  722.     *ramdac.colorMap = 0xff;
  723.     Mach_EmptyWriteBuffer();
  724.     *ramdac.colorMap = 0xff;
  725.     Mach_EmptyWriteBuffer();
  726.     *ramdac.colorMap = 0xff;
  727.     Mach_EmptyWriteBuffer();
  728.     }
  729.     for (i = 0;i < 3; i++) {
  730.     bgRgb[i] = 0x00;
  731.     fgRgb[i] = 0xff;
  732.     }
  733.  
  734. }
  735.  
  736.  
  737. /*
  738.  * ----------------------------------------------------------------------------
  739.  *
  740.  * RAMDACInit --
  741.  *
  742.  *    Initialize the RAMDAC.
  743.  *
  744.  * Results:
  745.  *    None.
  746.  *
  747.  * Side effects:
  748.  *    None.
  749.  *
  750.  * ----------------------------------------------------------------------------
  751.  */
  752. static void
  753. RAMDACInit()
  754. {
  755.  
  756. #if 0
  757.     /*
  758.      * Set up command register 0.
  759.      */
  760.     *ramdac.addrHighPtr = 0x2;
  761.     *ramdac.addrLowPtr = 0x1;
  762.     Mach_EmptyWriteBuffer();
  763.     *ramdac.regPtr = 0x80;
  764.     /*
  765.      * See note on page 4 of PMAG-BA doc.
  766.      */
  767.     {
  768.     volatile char    *addr = (char *) ROM2_ADDR;
  769.     *addr = 1;
  770.     }
  771.     /*
  772.      * Set up command register 1.
  773.      */
  774.     *ramdac.addrHighPtr = 0x2;
  775.     *ramdac.addrLowPtr = 0x2;
  776.     Mach_EmptyWriteBuffer();
  777.     *ramdac.regPtr = 0x00;
  778.     /*
  779.      * Set up command register 2.
  780.      */
  781.     *ramdac.addrHighPtr = 0x2;
  782.     *ramdac.addrLowPtr = 0x3;
  783.     Mach_EmptyWriteBuffer();
  784.     *ramdac.regPtr = 0x00;
  785.  
  786. #endif
  787.     /*
  788.      * Set up cursor command register. Enable both planes of the cursor
  789.      * and stop the damn blinking.
  790.      */
  791.     *ramdac.addrHighPtr = 0x3;
  792.     *ramdac.addrLowPtr = 0x0;
  793.     Mach_EmptyWriteBuffer();
  794.     *ramdac.regPtr = 0xc0;
  795.     Mach_EmptyWriteBuffer();
  796. }
  797.  
  798.  
  799.  
  800.  
  801. /*
  802.  * ----------------------------------------------------------------------------
  803.  *
  804.  * LoadColorMap --
  805.  *
  806.  *    Load the color map.
  807.  *
  808.  * Results:
  809.  *    None.
  810.  *
  811.  * Side effects:
  812.  *    The color map is loaded.
  813.  *
  814.  * ----------------------------------------------------------------------------
  815.  */
  816. static void
  817. LoadColorMap(ptr)
  818.     DevColorMap  *ptr;
  819. {
  820.     if(ptr->index > 256) {
  821.      return;
  822.     }
  823.  
  824.     *ramdac.addrHighPtr = 0x0;
  825.     *ramdac.addrLowPtr = ptr->index;
  826.     Mach_EmptyWriteBuffer();
  827.     *ramdac.colorMap = ptr->entry.red;
  828.     Mach_EmptyWriteBuffer();
  829.     *ramdac.colorMap = ptr->entry.green;
  830.     Mach_EmptyWriteBuffer();
  831.     *ramdac.colorMap = ptr->entry.blue;
  832.     Mach_EmptyWriteBuffer();
  833. }
  834.  
  835. static Boolean    consoleCmdDown = FALSE;
  836.  
  837.  
  838. /*
  839.  *----------------------------------------------------------------------
  840.  *
  841.  * DevGraphicsKbdIntr --
  842.  *
  843.  *    Process a received character.
  844.  *
  845.  * Results:
  846.  *    None.
  847.  *
  848.  * Side effects:
  849.  *    Events added to the queue.
  850.  *
  851.  *----------------------------------------------------------------------
  852.  */
  853. void
  854. DevGraphicsKbdIntr(ch)
  855.     unsigned char ch;
  856. {
  857.     int        i;
  858.     Time    time;
  859.     DevEvent    *eventPtr;
  860.     
  861.     if (ch == LK_POWER_ERROR || ch == LK_KDOWN_ERROR ||
  862.     ch == LK_INPUT_ERROR || ch == LK_OUTPUT_ERROR) {
  863.     if(!inKBDReset) {
  864.         printf("\n: RecvIntr: keyboard error,code=%x", ch);
  865.         KBDReset();
  866.     }
  867.     return;
  868.     }
  869.     if (ch < LK_LOWEST) {
  870.        return;
  871.     }
  872.     if (ch == KEY_UP) {
  873.     consoleCmdDown = FALSE;
  874.     } else if (ch == KEY_COMMAND) {
  875.     consoleCmdDown = TRUE;
  876.     } else if (consoleCmdDown) {
  877.     char asciiChar;
  878.  
  879.     consoleCmdDown = FALSE;
  880.     asciiChar = DevDC7085TranslateKey(ch, FALSE, FALSE);
  881.     if (asciiChar != -1) {
  882.         Dev_InvokeConsoleCmd(asciiChar);
  883.         return;
  884.     }
  885.     }
  886.  
  887.     /*
  888.      * See if there is room in the queue.
  889.      */
  890.     i = DEV_EVROUND(scrInfoPtr->eventQueue.eTail + 1);
  891.     if (i == scrInfoPtr->eventQueue.eHead) {
  892.     return;
  893.     }
  894.  
  895.     /*
  896.      * Add the event to the queue.
  897.      */
  898.     eventPtr = &events[scrInfoPtr->eventQueue.eTail];
  899.     eventPtr->type = DEV_BUTTON_RAW_TYPE;
  900.     eventPtr->device = DEV_KEYBOARD_DEVICE;
  901.     eventPtr->x = scrInfoPtr->mouse.x;
  902.     eventPtr->y = scrInfoPtr->mouse.y;
  903.     Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  904.     eventPtr->time = TO_MS(time);
  905.     eventPtr->key = ch;
  906.     scrInfoPtr->eventQueue.eTail = i;
  907.     dev_LastConsoleInput = time;
  908.     Fsio_DevNotifyReader(notifyToken);
  909. }
  910.  
  911.  
  912. /*
  913.  *----------------------------------------------------------------------
  914.  *
  915.  * DevGraphicsMouseIntr --
  916.  *
  917.  *    Process a received mouse character.
  918.  *
  919.  * Results:
  920.  *    None.
  921.  *
  922.  * Side effects:
  923.  *    Events added to the queue.
  924.  *
  925.  *----------------------------------------------------------------------
  926.  */
  927. void
  928. DevGraphicsMouseIntr(ch)
  929.     unsigned char ch;
  930. {
  931.     MouseReport    *newRepPtr;
  932.  
  933.     newRepPtr = ¤tRep;
  934.     newRepPtr->byteCount++;
  935.     if (ch & MOUSE_START_FRAME) {
  936.     /*
  937.      * The first mouse report byte (button state).
  938.      */
  939.     newRepPtr->state = ch;
  940.     if (newRepPtr->byteCount > 1) {
  941.         newRepPtr->byteCount = 1;
  942.     }
  943.     } else if (newRepPtr->byteCount == 2) {
  944.     /*
  945.      * The second mouse report byte (delta x).
  946.      */
  947.     newRepPtr->dx = ch;
  948.     } else if (newRepPtr->byteCount == 3) {
  949.     /*
  950.      * The final mouse report byte (delta y).
  951.      */
  952.     newRepPtr->dy = ch;
  953.     newRepPtr->byteCount = 0;
  954.     if (newRepPtr->dx != 0 || newRepPtr->dy != 0) {
  955.         /*
  956.          * If the mouse moved, post a motion event.
  957.          */
  958.         MouseEvent(newRepPtr);
  959.     }
  960.     MouseButtons(newRepPtr);
  961.     }
  962. }
  963.  
  964.  
  965. /*
  966.  *----------------------------------------------------------------------
  967.  *
  968.  * MouseEvent --
  969.  *
  970.  *    Process a mouse event.
  971.  *
  972.  * Results:
  973.  *    None.
  974.  *
  975.  * Side effects:
  976.  *    An event is added to the event queue.
  977.  *
  978.  *----------------------------------------------------------------------
  979.  */
  980. static void
  981. MouseEvent(newRepPtr) 
  982.     MouseReport    *newRepPtr;
  983. {
  984.     Time    time;
  985.     unsigned    milliSec;
  986.     int        i;
  987.     DevEvent    *eventPtr;
  988.     static     int lastAdd = 0;
  989.     static     int lastUpdate = 0;
  990.  
  991.     Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  992.     milliSec = TO_MS(time);
  993.  
  994.     /*
  995.      * Check to see if we have to accelerate the mouse
  996.      */
  997.     if (scrInfoPtr->mscale >=0) {
  998.     if (newRepPtr->dx >= scrInfoPtr->mthreshold) {
  999.         newRepPtr->dx +=
  1000.             (newRepPtr->dx - scrInfoPtr->mthreshold) * scrInfoPtr->mscale;
  1001.     }
  1002.     if (newRepPtr->dy >= scrInfoPtr->mthreshold) {
  1003.         newRepPtr->dy +=
  1004.         (newRepPtr->dy - scrInfoPtr->mthreshold) * scrInfoPtr->mscale;
  1005.     }
  1006.     }
  1007.     
  1008.     /*
  1009.      * Update mouse position
  1010.      */
  1011.     if( newRepPtr->state & MOUSE_X_SIGN) {
  1012.     scrInfoPtr->mouse.x += newRepPtr->dx;
  1013.     if (scrInfoPtr->mouse.x > scrInfoPtr->maxCurX) {
  1014.         scrInfoPtr->mouse.x = scrInfoPtr->maxCurX;
  1015.     }
  1016.     } else {
  1017.     scrInfoPtr->mouse.x -= newRepPtr->dx;
  1018.     if (scrInfoPtr->mouse.x < scrInfoPtr->minCurX) {
  1019.         scrInfoPtr->mouse.x = scrInfoPtr->minCurX;
  1020.     }
  1021.     }
  1022.     if( newRepPtr->state & MOUSE_Y_SIGN) {
  1023.     scrInfoPtr->mouse.y -= newRepPtr->dy;
  1024.     if (scrInfoPtr->mouse.y < scrInfoPtr->minCurY) {
  1025.         scrInfoPtr->mouse.y = scrInfoPtr->minCurY;
  1026.     }
  1027.     } else {
  1028.     scrInfoPtr->mouse.y += newRepPtr->dy;
  1029.     if (scrInfoPtr->mouse.y > scrInfoPtr->maxCurY) {
  1030.         scrInfoPtr->mouse.y = scrInfoPtr->maxCurY;
  1031.     }
  1032.     }
  1033.     if (devGraphicsOpen) {
  1034.     /*
  1035.      * Move the hardware cursor.
  1036.      */
  1037.     PosCursor(scrInfoPtr->mouse.x, scrInfoPtr->mouse.y);
  1038.     }
  1039.     /*
  1040.      * Store the motion event in the motion buffer.
  1041.      */
  1042.     tcs[scrInfoPtr->eventQueue.tcNext].time = milliSec;
  1043.     tcs[scrInfoPtr->eventQueue.tcNext].x = scrInfoPtr->mouse.x;
  1044.     tcs[scrInfoPtr->eventQueue.tcNext].y = scrInfoPtr->mouse.y;
  1045.     scrInfoPtr->eventQueue.tcNext++;
  1046.     if (scrInfoPtr->eventQueue.tcNext >= MOTION_BUFFER_SIZE) {
  1047.     scrInfoPtr->eventQueue.tcNext = 0;
  1048.     }
  1049.     if (scrInfoPtr->mouse.y < scrInfoPtr->mbox.bottom &&
  1050.     scrInfoPtr->mouse.y >=  scrInfoPtr->mbox.top &&
  1051.     scrInfoPtr->mouse.x < scrInfoPtr->mbox.right &&
  1052.     scrInfoPtr->mouse.x >=  scrInfoPtr->mbox.left) {
  1053.     return;
  1054.     }
  1055.  
  1056.     scrInfoPtr->mbox.bottom = 0;
  1057.     if (DEV_EVROUND(scrInfoPtr->eventQueue.eTail + 1) == scrInfoPtr->eventQueue.eHead) {
  1058.     return;
  1059.     }
  1060.  
  1061.     i = DEV_EVROUND(scrInfoPtr->eventQueue.eTail -1);
  1062.     if ((scrInfoPtr->eventQueue.eTail != scrInfoPtr->eventQueue.eHead) && 
  1063.         (i != scrInfoPtr->eventQueue.eHead)) {
  1064.     DevEvent    *eventPtr;
  1065.     eventPtr = &events[i];
  1066.     if(eventPtr->type == DEV_MOTION_TYPE) {
  1067.         /*
  1068.          * On the ds5000/200 there is some kind of bug when doing partial
  1069.          * writes.  Sometimes the x,y fields of one event are in the first
  1070.          * word of a cache line, and the x,y fields of the next event are
  1071.          * in the last word of the same cache line.  In this case the line
  1072.          * is probably in the cache because the X server just read it, but
  1073.          * the write done by the kernel to the last word in the cache line
  1074.          * will not be seen by the Xserver, causing the mouse to jump.
  1075.          * It is almost as if the kernel is bypassing the cache and writing
  1076.          * directly to memory.  If we read the word before writing it the
  1077.          * problem goes away.  JHH 2/7/90.
  1078.          */
  1079.         eventPtr->x = scrInfoPtr->mouse.x;
  1080.         eventPtr->y = scrInfoPtr->mouse.y;
  1081.         eventPtr->time = milliSec;
  1082.         eventPtr->device = DEV_MOUSE_DEVICE;
  1083.         return;
  1084.     }
  1085.     } 
  1086.     /*
  1087.      * Put event into queue and wakeup any waiters.
  1088.      */
  1089.     eventPtr = &events[scrInfoPtr->eventQueue.eTail];
  1090.     /*
  1091.      * See comment above.
  1092.      */
  1093.     eventPtr->type = DEV_MOTION_TYPE;
  1094.     eventPtr->time = milliSec;
  1095.     eventPtr->x = scrInfoPtr->mouse.x;
  1096.     eventPtr->y = scrInfoPtr->mouse.y;
  1097.     eventPtr->device = DEV_MOUSE_DEVICE;
  1098.     scrInfoPtr->eventQueue.eTail = DEV_EVROUND(scrInfoPtr->eventQueue.eTail + 1);
  1099.     dev_LastConsoleInput = time;
  1100.     if (devGraphicsOpen) {
  1101.     Fsio_DevNotifyReader(notifyToken);
  1102.     }
  1103. }
  1104.  
  1105.  
  1106. /*
  1107.  *----------------------------------------------------------------------
  1108.  *
  1109.  * MouseButtons --
  1110.  *
  1111.  *    Process mouse buttons.
  1112.  *
  1113.  * Results:
  1114.  *    None.
  1115.  *
  1116.  * Side effects:
  1117.  *    None.
  1118.  *
  1119.  *----------------------------------------------------------------------
  1120.  */
  1121. static void
  1122. MouseButtons(newRepPtr)
  1123.     MouseReport    *newRepPtr;
  1124. {
  1125.     static char temp, oldSwitch, newSwitch;
  1126.     int        i, j;
  1127.     DevEvent    *eventPtr;
  1128.     Time    time;
  1129.  
  1130.     int        type;
  1131.     int        key;
  1132.  
  1133.     newSwitch = newRepPtr->state & 0x07;
  1134.     oldSwitch = lastRep.state & 0x07;
  1135.     
  1136.     temp = oldSwitch ^ newSwitch;
  1137.     if (temp != 0) {
  1138.     for (j = 1; j < 8; j <<= 1) {
  1139.         if ((j & temp) == 0) {
  1140.         continue;
  1141.         }
  1142.  
  1143.         /*
  1144.          * Check for room in the queue
  1145.          */
  1146.         i = DEV_EVROUND(scrInfoPtr->eventQueue.eTail+1);
  1147.         if (i == scrInfoPtr->eventQueue.eHead) {
  1148.         return;
  1149.         }
  1150.  
  1151.         /*
  1152.          * Put event into queue.
  1153.          */
  1154.         eventPtr = &events[scrInfoPtr->eventQueue.eTail];
  1155.         switch (j) {
  1156.         case RIGHT_BUTTON:
  1157.             key = eventPtr->key = DEV_EVENT_RIGHT_BUTTON;
  1158.             break;
  1159.         case MIDDLE_BUTTON:
  1160.             key = eventPtr->key = DEV_EVENT_MIDDLE_BUTTON;
  1161.             break;
  1162.         case LEFT_BUTTON:
  1163.             key = eventPtr->key = DEV_EVENT_LEFT_BUTTON;
  1164.             break;
  1165.         }
  1166.         if (newSwitch & j) {
  1167.         type = eventPtr->type = DEV_BUTTON_DOWN_TYPE;
  1168.         } else {
  1169.         type = eventPtr->type = DEV_BUTTON_UP_TYPE;
  1170.         }
  1171.         eventPtr->device = DEV_MOUSE_DEVICE;
  1172.  
  1173.         Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  1174.         eventPtr->time = TO_MS(time);
  1175.         eventPtr->x = scrInfoPtr->mouse.x;
  1176.         eventPtr->y = scrInfoPtr->mouse.y;
  1177.     }
  1178.     scrInfoPtr->eventQueue.eTail = i;
  1179.     if (devGraphicsOpen) {
  1180.         Fsio_DevNotifyReader(notifyToken);
  1181.     }
  1182.  
  1183.     /* 
  1184.      * Update the last report 
  1185.      */
  1186.     lastRep = currentRep;
  1187.     scrInfoPtr->mswitches = newSwitch;
  1188.     }
  1189. }
  1190.  
  1191.  
  1192. /*
  1193.  *----------------------------------------------------------------------
  1194.  *
  1195.  * PosCursor --
  1196.  *
  1197.  *    Postion the cursor.
  1198.  *
  1199.  * Results:
  1200.  *    None.
  1201.  *
  1202.  * Side effects:
  1203.  *    None.
  1204.  *
  1205.  *----------------------------------------------------------------------
  1206.  */
  1207. static void
  1208. PosCursor(x, y)
  1209.     register int x,y;
  1210. {
  1211.     int        pos;
  1212.     if( y < scrInfoPtr->minCurY || y > scrInfoPtr->maxCurY ) {
  1213.     y = scrInfoPtr->maxCurY;
  1214.     }
  1215.     if(x < scrInfoPtr->minCurX || x > scrInfoPtr->maxCurX) {
  1216.     x = scrInfoPtr->maxCurX;
  1217.     }
  1218.     scrInfoPtr->cursor.x = x;        /* keep track of real cursor*/
  1219.     scrInfoPtr->cursor.y = y;        /* position, indep. of mouse*/
  1220.  
  1221.     pos = x + 241 - 52 + 31;
  1222.     *ramdac.addrHighPtr = 0x3;
  1223.     *ramdac.addrLowPtr = 0x1;
  1224.     Mach_EmptyWriteBuffer();
  1225.     *ramdac.regPtr = (pos & 0xff);
  1226.     *ramdac.addrHighPtr = 0x3;
  1227.     *ramdac.addrLowPtr = 0x2;
  1228.     Mach_EmptyWriteBuffer();
  1229.     *ramdac.regPtr = ((pos >> 8) & 0xff);
  1230.     Mach_EmptyWriteBuffer();
  1231.  
  1232.     pos = y + 36 - 32 + 31;
  1233.     *ramdac.addrHighPtr = 0x3;
  1234.     *ramdac.addrLowPtr = 0x3;
  1235.     Mach_EmptyWriteBuffer();
  1236.     *ramdac.regPtr = (pos & 0xff);
  1237.     *ramdac.addrHighPtr = 0x3;
  1238.     *ramdac.addrLowPtr = 0x4;
  1239.     Mach_EmptyWriteBuffer();
  1240.     *ramdac.regPtr = ((pos >> 8) & 0xff);
  1241.     Mach_EmptyWriteBuffer();
  1242. }
  1243.  
  1244.  
  1245. /*
  1246.  *----------------------------------------------------------------------
  1247.  *
  1248.  * Scroll --
  1249.  *
  1250.  *    Scroll the screen.
  1251.  *
  1252.  * Results:
  1253.  *    None.
  1254.  *
  1255.  * Side effects:
  1256.  *    None.
  1257.  *
  1258.  *----------------------------------------------------------------------
  1259.  */
  1260. static void
  1261. Scroll()
  1262. {
  1263.     int    line;
  1264.     register int *dest, *src;
  1265.     register int *end;
  1266.     register int temp0,temp1,temp2,temp3;
  1267.     register int i, scanInc, lineCount;
  1268.  
  1269.  
  1270.     if (displayType != PMAGBA) {
  1271.     return;
  1272.     }
  1273.     /*
  1274.      *  The following is an optimization to cause the scrolling 
  1275.      *  of text to be memory limited.  Basically the writebuffer is 
  1276.      *  4 words (32 bits ea.) long so to achieve maximum speed we 
  1277.      *  read and write in multiples of 4 words. We also limit the 
  1278.      *  size to be 80 characters for more speed. 
  1279.      */
  1280.     lineCount = 40;
  1281.     scanInc = 96;
  1282.     line = 1920 * 8;
  1283.     src = (int *)(frameBuffer+line);
  1284.     dest = (int *)(frameBuffer);
  1285.     end = (int *)(frameBuffer+ (60 * line) - line);
  1286.     do {
  1287.     i = 0;
  1288.     do {
  1289.         temp0 = src[0];
  1290.         temp1 = src[1];
  1291.         temp2 = src[2];
  1292.         temp3 = src[3];
  1293.         dest[0] = temp0;
  1294.         dest[1] = temp1;
  1295.         dest[2] = temp2;
  1296.         dest[3] = temp3;
  1297.         dest += 4;
  1298.         src += 4;
  1299.         i++;
  1300.     } while(i < lineCount);
  1301.     src += scanInc;
  1302.     dest += scanInc;
  1303.     } while(src < end);
  1304.  
  1305.     /* 
  1306.      * Now zero out the last two lines 
  1307.      */
  1308.     bzero(frameBuffer+(scrInfoPtr->row * line),  3 * line);
  1309. }
  1310.  
  1311.  
  1312. /*
  1313.  *----------------------------------------------------------------------
  1314.  *
  1315.  * Dev_GraphicsPutc --
  1316.  *
  1317.  *    Write a character to the console.
  1318.  *
  1319.  * Results:
  1320.  *    None.
  1321.  *
  1322.  * Side effects:
  1323.  *    None.
  1324.  *
  1325.  *----------------------------------------------------------------------
  1326.  */
  1327. int 
  1328. Dev_GraphicsPutc(c)
  1329. register char c;
  1330. {
  1331.     MASTER_LOCK(&graphicsMutex);
  1332.  
  1333.     if (initialized && (displayType == PMAGBA)) {
  1334.     Blitc((unsigned char)(c & 0xff));
  1335.     } else {
  1336.     if (isascii(c)) {
  1337.         mach_MonFuncs.mputchar(c);
  1338.     }
  1339.     }
  1340.  
  1341.     MASTER_UNLOCK(&graphicsMutex);
  1342.  
  1343.     return(1);
  1344. }
  1345.  
  1346.  
  1347. /*
  1348.  *----------------------------------------------------------------------
  1349.  *
  1350.  * Blitc --
  1351.  *
  1352.  *    Write a character to the screen.
  1353.  *
  1354.  * Results:
  1355.  *    None.
  1356.  *
  1357.  * Side effects:
  1358.  *    None.
  1359.  *
  1360.  *----------------------------------------------------------------------
  1361.  */
  1362. static void
  1363. Blitc(c)
  1364.     register unsigned char c;
  1365. {
  1366.     register char *bRow, *fRow;
  1367.     register int i;
  1368.     register int ote = 1024; /* offset to table entry */
  1369.     int colMult = 8;
  1370.     extern char devFont[];
  1371.  
  1372.     c &= 0xff;
  1373.  
  1374.     switch ( c ) {
  1375.     case '\t':
  1376.         for(i = 8 - (scrInfoPtr->col & 0x7); i > 0; i--) {
  1377.         Blitc(' ');
  1378.         }
  1379.         break;
  1380.     case '\r':
  1381.         scrInfoPtr->col = 0;
  1382.         break;
  1383.     case '\b':
  1384.         scrInfoPtr->col--;
  1385.         if(scrInfoPtr->col < 0) {
  1386.         scrInfoPtr->col = 0;
  1387.         }
  1388.         break;
  1389.     case '\n':
  1390.         if(scrInfoPtr->row + 1 >= scrInfoPtr->maxRow) {
  1391.         Scroll();
  1392.         } else {
  1393.         scrInfoPtr->row++;
  1394.         }
  1395.         scrInfoPtr->col = 0;
  1396.         break;
  1397.     case '\007':
  1398.         DevDC7085KBDPutc(LK_RING_BELL);
  1399.         break;
  1400.     default:
  1401.         /*
  1402.          * If the next character will wrap around then 
  1403.          * increment row counter or scroll screen.
  1404.          */
  1405.         if (scrInfoPtr->col >= scrInfoPtr->maxCol) {
  1406.         scrInfoPtr->col = 0;
  1407.         if(scrInfoPtr->row + 1 >= scrInfoPtr->maxRow) {
  1408.             Scroll();
  1409.         } else {
  1410.             scrInfoPtr->row++;
  1411.         }
  1412.         }
  1413.         /*
  1414.          * xA1 to XFD are the printable characters added with 8-bit
  1415.          * support.
  1416.          */
  1417.         if ((c >= ' ' && c <= '~') || (c >= 0xA1 && c <= 0xFD)) {
  1418.         bRow = frameBuffer + (scrInfoPtr->row * 15 & 0x3ff) * ote + 
  1419.                scrInfoPtr->col * colMult;
  1420.         i = c - ' ';
  1421.         if(i < 0 || i > 221) {
  1422.             i = 0;
  1423.         } else {
  1424.             /* These are to skip the (32) 8-bit 
  1425.              * control chars, as well as DEL 
  1426.              * and 0xA0 which aren't printable */
  1427.             if (c > '~') {
  1428.             i -= 34; 
  1429.             }
  1430.             i *= 15;
  1431.         }
  1432.         fRow = (char *)((int)devFont + i);
  1433.  
  1434.         /* inline expansion for speed */
  1435.         {
  1436.             int j;
  1437.             unsigned int *pInt;
  1438.  
  1439.             pInt = (unsigned int *) bRow;
  1440.             for(j = 0; j < 15; j++) {
  1441.             /*
  1442.              * fontmaskBits converts a nibble
  1443.              * (4 bytes) to a long word 
  1444.              * containing 4 pixels corresponding
  1445.              * to each bit in the nibble.  Thus
  1446.              * we write two longwords for each
  1447.              * byte in font.
  1448.              * 
  1449.              * Remember the font is 8 bits wide
  1450.              * and 15 bits high.
  1451.              *
  1452.              * We add 256 to the pointer to
  1453.              * point to the pixel on the 
  1454.              * next scan line
  1455.              * directly below the current
  1456.              * pixel.
  1457.              */
  1458.             *pInt =  fontmaskBits[(*fRow)&0xf];
  1459.             *(pInt+1)= fontmaskBits[((*fRow)>>4)&0xf];
  1460.             fRow++; 
  1461.             pInt += 256;
  1462.             }
  1463.         }
  1464.         scrInfoPtr->col++; /* increment column counter */
  1465.     }
  1466.     }
  1467.     if (!devGraphicsOpen) {
  1468.     PosCursor(scrInfoPtr->col * 8, scrInfoPtr->row * 15);
  1469.     }
  1470. }
  1471.  
  1472.  
  1473. /*
  1474.  *----------------------------------------------------------------------
  1475.  *
  1476.  * DevGraphicsOpen --
  1477.  *
  1478.  *    Open the graphics device.
  1479.  *
  1480.  * Results:
  1481.  *    None.
  1482.  *
  1483.  * Side effects:
  1484.  *    None.
  1485.  *
  1486.  *----------------------------------------------------------------------
  1487.  */
  1488. /*ARGSUSED*/
  1489. ReturnStatus
  1490. DevGraphicsOpen(devicePtr, useFlags, inNotifyToken, flagsPtr)
  1491.     Fs_Device *devicePtr;    /* Specifies type and unit number. */
  1492.     int useFlags;        /* Flags from the stream being opened */
  1493.     ClientData inNotifyToken;    /* Used for Fs call-back to notify waiting
  1494.                  * processes that the console device is ready.*/
  1495.     int        *flagsPtr;    /* Device open flags. */
  1496. {
  1497.     Time        time;
  1498.     ReturnStatus    status = SUCCESS;
  1499.  
  1500.     MASTER_LOCK(&graphicsMutex);
  1501.  
  1502.     if (displayType != PMAGBA) {
  1503.     status = DEV_NO_DEVICE;
  1504.     goto exit;
  1505.     }
  1506.     if (devicePtr->unit == DEV_MOUSE_UNIT) {
  1507.     if (devGraphicsOpen) {
  1508.         status = FS_FILE_BUSY;
  1509.         goto exit;
  1510.     }
  1511.     devGraphicsOpen = TRUE;
  1512.     devDivertXInput = FALSE;
  1513.     notifyToken = inNotifyToken;
  1514.     InitColorMap();
  1515.     /*
  1516.      * Set up event queue for later
  1517.      */
  1518.     scrInfoPtr->eventQueue.events = events;
  1519.     scrInfoPtr->eventQueue.tcs = tcs;
  1520.     scrInfoPtr->cursorBits = (short *)(cursorBits);
  1521.     scrInfoPtr->bitmap = (Address) (frameBuffer);
  1522.     scrInfoPtr->eventQueue.eSize = DEV_MAXEVQ;
  1523.     scrInfoPtr->eventQueue.eHead = scrInfoPtr->eventQueue.eTail = 0;
  1524.     scrInfoPtr->eventQueue.tcSize = MOTION_BUFFER_SIZE;
  1525.     scrInfoPtr->eventQueue.tcNext = 0;
  1526.     Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  1527.     scrInfoPtr->eventQueue.timestampMS = TO_MS(time);
  1528.     }
  1529. exit:
  1530.     MASTER_UNLOCK(&graphicsMutex);
  1531.     return(status);
  1532. }
  1533.  
  1534.  
  1535. /*
  1536.  *----------------------------------------------------------------------
  1537.  *
  1538.  * DevGraphicsClose --
  1539.  *
  1540.  *    Close the graphics device.
  1541.  *
  1542.  * Results:
  1543.  *    None.
  1544.  *
  1545.  * Side effects:
  1546.  *    None.
  1547.  *
  1548.  *----------------------------------------------------------------------
  1549.  */
  1550. /*ARGSUSED*/
  1551. ReturnStatus
  1552. DevGraphicsClose(devicePtr, useFlags, openCount, writerCount)
  1553.     Fs_Device    *devicePtr;    /* Device information. */
  1554.     int        useFlags;    /* FS_READ | FS_WRITE */
  1555.     int        openCount;    /* Number of times still open. */
  1556.     int        writerCount;    /* Number of times still open for writing. */
  1557. {
  1558.     MASTER_LOCK(&graphicsMutex);
  1559.  
  1560.     if (devicePtr->unit == DEV_MOUSE_UNIT) {
  1561.     if (!devGraphicsOpen) {
  1562.         MASTER_UNLOCK(&graphicsMutex);
  1563.         return(FS_FILE_BUSY);
  1564.     }
  1565.     devGraphicsOpen = FALSE;
  1566.     InitColorMap();
  1567.     ScreenInit();
  1568.     VmMach_UserUnmap((Address) NIL);
  1569.     }
  1570.     MASTER_UNLOCK(&graphicsMutex);
  1571.     return(SUCCESS);
  1572. }
  1573.  
  1574.  
  1575. /*
  1576.  *----------------------------------------------------------------------
  1577.  *
  1578.  * DevGraphicsRead --
  1579.  *
  1580.  *    Read from the graphics device.
  1581.  *
  1582.  * Results:
  1583.  *    None.
  1584.  *
  1585.  * Side effects:
  1586.  *    None.
  1587.  *
  1588.  *----------------------------------------------------------------------
  1589.  */
  1590. /*ARGSUSED*/
  1591. ReturnStatus
  1592. DevGraphicsRead(devicePtr, readPtr, replyPtr)
  1593.     Fs_Device    *devicePtr;    /* Device to read from */
  1594.     Fs_IOParam    *readPtr;    /* Read parameter block */
  1595.     Fs_IOReply    *replyPtr;    /* Return length and signal */ 
  1596. {
  1597. }
  1598.  
  1599.  
  1600. /*
  1601.  *----------------------------------------------------------------------
  1602.  *
  1603.  * DevGraphicsWrite --
  1604.  *
  1605.  *    Write to the graphics device.
  1606.  *
  1607.  * Results:
  1608.  *    None.
  1609.  *
  1610.  * Side effects:
  1611.  *    None.
  1612.  *
  1613.  *----------------------------------------------------------------------
  1614.  */
  1615. /*ARGSUSED*/
  1616. ReturnStatus
  1617. DevGraphicsWrite(devicePtr, writePtr, replyPtr)
  1618.     Fs_Device    *devicePtr;    /* Indicates device */    
  1619.     Fs_IOParam    *writePtr;    /* Standard write parameter block */
  1620.     Fs_IOReply    *replyPtr;    /* Return length and signal */
  1621. {
  1622. }
  1623.  
  1624.  
  1625. /*
  1626.  *----------------------------------------------------------------------
  1627.  *
  1628.  * DevGraphicsIOControl --
  1629.  *
  1630.  *    Perform an io control on the graphics device.
  1631.  *
  1632.  * Results:
  1633.  *    None.
  1634.  *
  1635.  * Side effects:
  1636.  *    None.
  1637.  *
  1638.  *----------------------------------------------------------------------
  1639.  */
  1640. /*ARGSUSED*/
  1641. ReturnStatus
  1642. DevGraphicsIOControl(devicePtr, ioctlPtr, replyPtr)
  1643.     Fs_Device        *devicePtr;
  1644.     Fs_IOCParam        *ioctlPtr;
  1645.     Fs_IOReply        *replyPtr;
  1646. {
  1647.     ReturnStatus status = SUCCESS;
  1648.     int        isColor;
  1649.  
  1650.     MASTER_LOCK(&graphicsMutex);
  1651.  
  1652.     switch (ioctlPtr->command) {
  1653.     case IOC_GRAPHICS_GET_INFO: {
  1654.         char        *addr;
  1655.         Proc_ControlBlock    *procPtr;
  1656.         /*
  1657.          * Map the screen info struct into the user's address space.
  1658.          */
  1659.         status = VmMach_UserMap(sizeof(DevScreenInfo), (Address) NIL,
  1660.         (Address)scrInfoPtr, FALSE, &addr);
  1661.         if (status != SUCCESS) {
  1662.         goto mapError;
  1663.         }
  1664.         bcopy((char *)&addr, ioctlPtr->outBuffer, sizeof(addr));
  1665.         /*
  1666.          * Map the events into the user's address space.
  1667.          */
  1668.         status = VmMach_UserMap(sizeof(events), (Address) NIL, 
  1669.             (Address)events, FALSE, &addr); 
  1670.         if (status != SUCCESS) {
  1671.         goto mapError;
  1672.         }
  1673.         scrInfoPtr->eventQueue.events = (DevEvent *)addr;
  1674.         /*
  1675.          * Map the tcs into the user's address space.
  1676.          */
  1677.         status = VmMach_UserMap(sizeof(tcs), (Address) NIL, (Address)tcs, 
  1678.         FALSE, &addr);
  1679.         if (status != SUCCESS) {
  1680.         goto mapError;
  1681.         }
  1682.         scrInfoPtr->eventQueue.tcs = (DevTimeCoord *)addr;
  1683.         /*
  1684.          * Map the plane mask into the user's address space.
  1685.          */
  1686.         status = VmMach_UserMap(sizeof(planeMask), (Address) NIL, 
  1687.             (Address)&planeMask, FALSE, &addr);
  1688.         if (status != SUCCESS) {
  1689.         goto mapError;
  1690.         }
  1691.         scrInfoPtr->planeMask = (char *)addr;
  1692.         /*
  1693.          * Map the bitmap into the user's address space.
  1694.          */
  1695.         status = VmMach_UserMap(1024*1024, (Address) NIL,
  1696.                   (Address)scrInfoPtr->bitmap, FALSE, &addr);
  1697.         if (status != SUCCESS) {
  1698.         goto mapError;
  1699.         }
  1700.         scrInfoPtr->bitmap = (char *)addr;
  1701.         break;
  1702. mapError:    
  1703.         VmMach_UserUnmap((Address) NIL);
  1704.         status = FS_BUFFER_TOO_BIG;
  1705.         printf("Cannot map shared data structures\n");
  1706.         break;
  1707.     }
  1708.  
  1709.     case IOC_GRAPHICS_MOUSE_POS:
  1710.         /*
  1711.          * Set mouse state.
  1712.          */
  1713.         scrInfoPtr->mouse = *((DevCursor *)ioctlPtr->inBuffer);
  1714.         PosCursor(scrInfoPtr->mouse.x, scrInfoPtr->mouse.y );
  1715.         break;
  1716.  
  1717.     case IOC_GRAPHICS_INIT_SCREEN:    
  1718.         /*
  1719.          * Initialize the screen.
  1720.          */
  1721.         ScreenInit();
  1722.         break;
  1723.  
  1724.     case IOC_GRAPHICS_KBD_CMD: {
  1725.         DevKpCmd        *kpCmdPtr;
  1726.         unsigned char    *cp;
  1727.  
  1728.         kpCmdPtr = (DevKpCmd *)ioctlPtr->inBuffer;
  1729.         if (kpCmdPtr->nbytes == 0) {
  1730.         kpCmdPtr->cmd |= 0x80;
  1731.         }
  1732.         if (!devGraphicsOpen) {
  1733.         kpCmdPtr->cmd |= 1;
  1734.         }
  1735.         DevDC7085KBDPutc((int)kpCmdPtr->cmd);
  1736.         cp = &kpCmdPtr->par[0];
  1737.         for (cp = &kpCmdPtr->par[0]; 
  1738.              kpCmdPtr->nbytes > 0;
  1739.          cp++, kpCmdPtr->nbytes--) {
  1740.         if(kpCmdPtr->nbytes == 1) {
  1741.             *cp |= 0x80;
  1742.         }
  1743.         DevDC7085KBDPutc((int)*cp);
  1744.         }
  1745.         break;
  1746.     }
  1747.  
  1748.     case IOC_GRAPHICS_GET_INFO_ADDR:    
  1749.         *(DevScreenInfo **)ioctlPtr->outBuffer = scrInfoPtr;
  1750.         break;
  1751.  
  1752.     case IOC_GRAPHICS_CURSOR_BIT_MAP:
  1753.         LoadCursor((unsigned short *)ioctlPtr->inBuffer);
  1754.         break;
  1755.  
  1756.     case IOC_GRAPHICS_CURSOR_COLOR:
  1757.         CursorColor((unsigned int *)ioctlPtr->inBuffer);
  1758.         break;
  1759.          
  1760.         case IOC_GRAPHICS_COLOR_MAP:
  1761.         LoadColorMap((DevColorMap *)ioctlPtr->inBuffer);
  1762.         break;
  1763.  
  1764.     case IOC_GRAPHICS_KERN_LOOP: 
  1765.         printf("DevGraphicsIOControl: QIOKERNLOOP\n");
  1766.         break;
  1767.  
  1768.     case IOC_GRAPHICS_KERN_UNLOOP: 
  1769.         printf("DevGraphicsIOControl: QIOKERNUNLOOP\n");
  1770.         break;
  1771.  
  1772.     case IOC_GRAPHICS_VIDEO_ON:
  1773.         break;
  1774.  
  1775.     case IOC_GRAPHICS_VIDEO_OFF:
  1776.         break;
  1777.     case    IOC_GET_FLAGS:
  1778.     case    IOC_SET_FLAGS:
  1779.     case    IOC_SET_BITS:
  1780.     case    IOC_CLEAR_BITS:
  1781.         /*
  1782.          * No graphics specific bits are set this way.
  1783.          */
  1784.         break;
  1785.     case IOC_GRAPHICS_IS_COLOR:
  1786.         isColor = 1;
  1787.         bcopy((char *)&isColor, ioctlPtr->outBuffer, sizeof (int));
  1788.         break;
  1789.  
  1790.     default:
  1791.         printf("DevGraphicsIOControl: Unknown command %d\n", 
  1792.            ioctlPtr->command);
  1793.         status = FS_INVALID_ARG;
  1794.         break;
  1795.     }
  1796.  
  1797.     MASTER_UNLOCK(&graphicsMutex);
  1798.     return(status);
  1799. }
  1800.  
  1801.  
  1802. /*
  1803.  *----------------------------------------------------------------------
  1804.  *
  1805.  * DevGraphicsSelect --
  1806.  *
  1807.  *    Perform a select on the graphics device.
  1808.  *
  1809.  * Results:
  1810.  *    None.
  1811.  *
  1812.  * Side effects:
  1813.  *    None.
  1814.  *
  1815.  *----------------------------------------------------------------------
  1816.  */
  1817. ReturnStatus
  1818. DevGraphicsSelect(devicePtr, readPtr, writePtr, exceptPtr)
  1819.     Fs_Device            *devicePtr;
  1820.     int            *readPtr;
  1821.     int            *writePtr;
  1822.     int            *exceptPtr;
  1823. {
  1824.     ReturnStatus status = SUCCESS;
  1825.  
  1826.     MASTER_LOCK(&graphicsMutex);
  1827.  
  1828.     if (*readPtr) {
  1829.     if (devicePtr->unit == DEV_MOUSE_UNIT) {
  1830.         if (scrInfoPtr->eventQueue.eHead == scrInfoPtr->eventQueue.eTail) {
  1831.         *readPtr = 0;
  1832.         }
  1833.     } else {
  1834.         *readPtr = 0;
  1835.     }
  1836.     }
  1837.  
  1838.     MASTER_UNLOCK(&graphicsMutex);
  1839.  
  1840.     *writePtr = *exceptPtr = 0;
  1841.  
  1842.     return(status);
  1843. }
  1844.  
  1845.  
  1846.  
  1847. /*
  1848.  *----------------------------------------------------------------------
  1849.  *
  1850.  * Dev_VidEnable --
  1851.  *
  1852.  *    Enables or disables the video display.
  1853.  *
  1854.  * Results:
  1855.  *    None.
  1856.  *
  1857.  * Side effects:
  1858.  *    Turns video on or off.
  1859.  *
  1860.  *----------------------------------------------------------------------
  1861.  */
  1862. ReturnStatus
  1863. Dev_VidEnable(onOff)
  1864. Boolean onOff;        /* TRUE if video is to be on. */
  1865. {
  1866.     return(SUCCESS);
  1867. }
  1868.